index.ts ➔ PluginCritical   C
last analyzed

Complexity

Conditions 9

Size

Total Lines 53
Code Lines 38

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 48
CRAP Score 9.0679

Importance

Changes 0
Metric Value
eloc 38
dl 0
loc 53
ccs 48
cts 53
cp 0.9057
rs 6.6346
c 0
b 0
f 0
cc 9
crap 9.0679

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1 1
import {Plugin} from 'rollup';
2 1
import * as path from 'path';
3 1
4 1
const criticalSuffix = '_critical.min.css';
5 1
6 1
/**
7 1
 * Default `criticalConfig` passed in to `critical`
8 1
 */
9 1
const defaultCriticalConfig: Partial<CriticalConfig> = {
10 1
  inline: false,
11 1
  extract: false,
12 1
  width: 1200,
13 1
  height: 1200,
14 1
  penthouse: {
15 1
    blockJSRequests: false
16 1
  }
17 1
};
18 1
19 1
/**
20 1
 * [Vite.js](https://vitejs.dev/) & [Rollup](https://rollupjs.org/) plugin for generating critical CSS
21 1
 * that uses the [critical](https://github.com/addyosmani/critical) generator under the hood.
22 1
 *
23 1
 * @param {CriticalPluginConfig} pluginConfig - the plugin configuration object
24 1
 * @param {Function} callback - callback upon completion of the critical CSS generation
25 1
 * @constructor
26 1
 */
27 2
function PluginCritical(pluginConfig: CriticalPluginConfig, callback?: CriticalPluginCallback): Plugin {
28 2
  return {
29 2
    name: 'critical',
30 2
    async writeBundle(outputOptions, bundle) {
31 2
      const css: Array<string> = [];
32 2
      // Find all of the generated CSS assets
33 2
      for (const chunk of Object.values(bundle)) {
34 2
        if (chunk.type === 'asset' && chunk.fileName.endsWith('.css')) {
35 2
          const cssFile = path.join(outputOptions.dir || '', chunk.fileName);
36 2
          css.push(cssFile);
37 2
        }
38 2
      }
39 2
      // If we have no CSS, skip bundle
40 2
      if (!css.length) {
41
        return;
42
      }
43 2
      // Iterate through the pages
44 2
      for (const page of pluginConfig.criticalPages) {
45 2
        const criticalBase = pluginConfig.criticalBase;
46 2
        const criticalSrc = pluginConfig.criticalUrl + page.uri;
47 2
        // If inline is set to true, use HTML as target, otherwise CSS with suffix
48 2
        const criticalTarget = (pluginConfig.criticalConfig && pluginConfig.criticalConfig.inline == true) ? page.template + ".html" : page.template + criticalSuffix;
49 2
        // Merge in our options
50 2
        const options = Object.assign(
51 2
            { css },
52 2
            defaultCriticalConfig,
53 2
            {
54 2
              base: criticalBase,
55 2
              src: criticalSrc,
56 2
              target: criticalTarget,
57 2
            },
58 2
            pluginConfig.criticalConfig
59 2
        );
60 2
        // Horrible nonsense to import an ESM module into CJS
61 2
        // ref: https://adamcoster.com/blog/commonjs-and-esm-importexport-compatibility-examples
62 2
        const generate = (await import('critical')).generate;
63 2
        // Generate the Critical CSS
64 2
        console.log(`Generating critical CSS from ${criticalSrc} to ${criticalTarget}`);
65 2
        await generate(options, (err: string) => {
66 2
          if (err) {
67
            console.error(err);
68
          }
69 2
          if (callback) {
70
            callback(err);
71
          }
72 2
        });
73 2
      }
74 2
    }
75 2
  }
76 2
}
77 1
78
export default PluginCritical;
79